/*
 * $Log: InformationWindow.java,v $ Revision 1.2 2006/11/05 13:58:01 wetzker
 * more merging - CLang + MF + some states still missing
 * 
 * Revision 1.1.28.1 2006/07/26 15:28:28 endert Formatted Code
 * 
 * Revision 1.1 2006/03/13 07:37:49 axle moved from ROOT/src for Maven 2
 * Buildsystem and Team/Soccerscope separation
 * 
 * Revision 1.4 2006/03/07 12:46:36 endert Merge after refactoring: - New
 * State-Interface: One Method for each action type - Action Bean removed -
 * ActionFactorys for helper methods, States calculate main-Action themselves -
 * formatted code - added State-List in Monitor (Context-Menu of Player) - other
 * smaller stuff
 * 
 * Revision 1.3.2.2 2006/03/06 23:17:50 endert Removed warnings, added
 * State-Overview to Context-Menu!
 * 
 * Revision 1.3.2.1 2006/02/25 22:07:31 wetzker formated
 * 
 * Revision 1.3 2006/02/22 16:04:48 endert This is done: - Rebound SoccerScope
 * to Agents (can be added or removed in config-file) - Situations now all
 * extend abstract class Situation - Refactorings: ActionBean _ removed from
 * Attributes - SoccerScope will automatically connect to host given in
 * Start-Call - Trainer uses the same host as soccerscope - Removed unused stuff
 * (old confs, bat, etc.) - Code formatted (good luck when merging) - organized
 * imports - all that i forgot to mention here
 * 
 * Revision 1.2 2005/06/19 19:44:37 till added parameter teamSide to constructor
 * of soccerscope.model.Player
 * 
 * Revision 1.1 2005/04/20 10:39:06 endert Fresh Team Repository installation
 * from /home/e/endert/Robocup to here.
 * 
 * Revision 1.3 2005/02/06 07:19:46 maketi Added soccerscope with connection to
 * our world model
 * 
 * Revision 1.6 2002/10/11 10:41:40 koji
 * �Х���5(HeteroParam),GoalȽ������
 * 
 * Revision 1.5 2002/10/04 10:39:20 koji
 * Tuple,Point,Vector�Υѥå������ѹ���Geometry,Circle,Line,Rectangle�ɲ�
 * 
 * Revision 1.4 2002/09/02 07:14:49 koji ButtunManger��Ƴ��
 * 
 * Revision 1.3 2002/09/02 07:06:19 taku-ako
 * Geometry��Ϣ�Υ饤�֥����.
 * 
 * Revision 1.2 2002/08/30 10:47:33 koji bmpviewer����Jimi�б�
 * 
 * Revision 1.1.1.1 2002/03/01 14:12:52 koji CVS�����
 * 
 */

package soccerscope.view;

import java.awt.Container;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.NumberFormat;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

import soccerscope.model.ClientScene;
import soccerscope.model.Param;
import soccerscope.model.Player;
import soccerscope.model.SoccerObjectID;
import soccerscope.model.Team;
import soccerscope.model.agentplan.CommentDB;
import soccerscope.util.geom.Point2f;
import soccerscope.util.geom.Tuple2f;

public class InformationWindow
    extends JFrame
    implements ScopeWindow, SoccerObjectID, SoccerObjectSelectObserver,
    MouseListener {

  private static final long  serialVersionUID = 3926358716905826321L;

  public final static String title            = "information";

  private ClientScene        clientScene;

  private Container          container        = null;

  private JTabbedPane        tabbedPane;

  private int                leftNumber;

  private int                rightNumber;

  private NumberFormat       nf;

  private String tuple2String(Tuple2f tuple) {

    return "(" + this.nf.format(tuple.x) + ", " + this.nf.format(tuple.y) + ")";
  }

  public InformationWindow() {

    // frame title
    super("information");

    // �����ѿ�ν��
    this.leftNumber = SoccerObjectID.LEFT_1;
    this.rightNumber = SoccerObjectID.RIGHT_1;
    this.nf = NumberFormat.getInstance();
    this.nf.setMaximumFractionDigits(2);

    // �%ߡ��ʥ�����
    this.clientScene = ClientScene.createScene();

    // get content pane
    this.container = this.getContentPane();

    this.tabbedPane = new JTabbedPane();
    this.tabbedPane.addTab("Left", this.createLeftPlayerPanel());
    this.tabbedPane.addTab("Right", this.createRightPlayerPanel());
    this.tabbedPane.addTab("Other", this.createOtherPanel());
    this.container.add(this.tabbedPane);

    this.pack();
    this.setResizable(false);
  }

  private PlayerButton lpButton;

  private JLabel       lpos;

  private JLabel       lvel;

  private JLabel       lacc;

  private JLabel       langle;

  private JLabel       lneck;

  private JLabel       lvisible;

  private JTextField   lmessage;

  private JTextArea    lcomment;

  private JPanel createLeftPlayerPanel() {

    JPanel jp = new JPanel();
    jp.setLayout(new BoxLayout(jp, BoxLayout.X_AXIS));
    JPanel jpw = new JPanel();
    jpw.setLayout(new BoxLayout(jpw, BoxLayout.Y_AXIS));
    JPanel jpc = new JPanel();
    jpc.setLayout(new BoxLayout(jpc, BoxLayout.Y_AXIS));
    JPanel jpe = new JPanel();
    jpe.setLayout(new BoxLayout(jpe, BoxLayout.Y_AXIS));
    jp.add(jpw);
    jp.add(Box.createHorizontalStrut(4));
    jp.add(jpc);
    jp.add(Box.createHorizontalStrut(16));
    jp.add(jpe);
    this.lpButton = new PlayerButton(new Player(Team.LEFT_SIDE));
    this.lpButton.addMouseListener(this);
    JPanel pButtonPanel = new JPanel();
    pButtonPanel.add(this.lpButton);
    jpw.add(pButtonPanel);
    this.lpos = new JLabel(new Point2f().toString());
    this.lvel = new JLabel(new Point2f().toString());
    this.lacc = new JLabel(new Point2f().toString());
    jpc.add(new JLabel("Position"));
    jpc.add(this.lpos);
    jpc.add(new JLabel("Velocity"));
    jpc.add(this.lvel);
    jpc.add(new JLabel("Acceleration"));
    jpc.add(this.lacc);
    this.langle = new JLabel("0");
    this.lneck = new JLabel("0");
    this.lvisible = new JLabel("0");
    jpe.add(new JLabel("BodyAngle"));
    jpe.add(this.langle);
    jpe.add(new JLabel("NeckAngle"));
    jpe.add(this.lneck);
    jpe.add(new JLabel("VisibleAngle"));
    jpe.add(this.lvisible);

    JPanel leftplayerPanel = new JPanel();
    leftplayerPanel.setLayout(new BoxLayout(leftplayerPanel, BoxLayout.Y_AXIS));
    this.lmessage = new JTextField();
    this.lcomment = new JTextArea(4, 0);
    JScrollPane jsp = new JScrollPane(this.lcomment);
    leftplayerPanel.add(jp);
    leftplayerPanel.add(this.lmessage);
    leftplayerPanel.add(jsp);
    return leftplayerPanel;
  }

  private PlayerButton rpButton;

  private JLabel       rpos;

  private JLabel       rvel;

  private JLabel       racc;

  private JLabel       rangle;

  private JLabel       rneck;

  private JLabel       rvisible;

  private JTextField   rmessage;

  private JTextArea    rcomment;

  private JPanel createRightPlayerPanel() {

    JPanel jp = new JPanel();
    jp.setLayout(new BoxLayout(jp, BoxLayout.X_AXIS));
    JPanel jpw = new JPanel();
    jpw.setLayout(new BoxLayout(jpw, BoxLayout.Y_AXIS));
    JPanel jpc = new JPanel();
    jpc.setLayout(new BoxLayout(jpc, BoxLayout.Y_AXIS));
    JPanel jpe = new JPanel();
    jpe.setLayout(new BoxLayout(jpe, BoxLayout.Y_AXIS));
    jp.add(jpw);
    jp.add(Box.createHorizontalStrut(4));
    jp.add(jpc);
    jp.add(Box.createHorizontalStrut(16));
    jp.add(jpe);
    this.rpButton = new PlayerButton(new Player(Team.RIGHT_SIDE));
    this.rpButton.addMouseListener(this);
    JPanel pButtonPanel = new JPanel();
    pButtonPanel.add(this.rpButton);
    jpw.add(pButtonPanel);
    this.rpos = new JLabel(new Point2f().toString());
    this.rvel = new JLabel(new Point2f().toString());
    this.racc = new JLabel(new Point2f().toString());
    jpc.add(new JLabel("Position"));
    jpc.add(this.rpos);
    jpc.add(new JLabel("Velocity"));
    jpc.add(this.rvel);
    jpc.add(new JLabel("Acceleration"));
    jpc.add(this.racc);
    this.rangle = new JLabel("0");
    this.rneck = new JLabel("0");
    this.rvisible = new JLabel("0");
    jpe.add(new JLabel("BodyAngle"));
    jpe.add(this.rangle);
    jpe.add(new JLabel("NeckAngle"));
    jpe.add(this.rneck);
    jpe.add(new JLabel("VisibleAngle"));
    jpe.add(this.rvisible);

    JPanel rightplayerPanel = new JPanel();
    rightplayerPanel
        .setLayout(new BoxLayout(rightplayerPanel, BoxLayout.Y_AXIS));
    this.rmessage = new JTextField();
    this.rcomment = new JTextArea(4, 0);
    JScrollPane jsp = new JScrollPane(this.rcomment);
    rightplayerPanel.add(jp);
    rightplayerPanel.add(this.rmessage);
    rightplayerPanel.add(jsp);
    return rightplayerPanel;
  }

  private JLabel ballpos;

  private JLabel ballvel;

  private JLabel ballacc;

  private JPanel createOtherPanel() {

    JPanel otherPanel = new JPanel();
    otherPanel.setLayout(new BoxLayout(otherPanel, BoxLayout.Y_AXIS));
    otherPanel.setBorder(new TitledBorder("Ball"));
    this.ballpos = new JLabel(new Point2f().toString());
    this.ballvel = new JLabel(new Point2f().toString());
    this.ballacc = new JLabel(new Point2f().toString());
    otherPanel.add(new JLabel("Position"));
    otherPanel.add(this.ballpos);
    otherPanel.add(new JLabel("Velocity"));
    otherPanel.add(this.ballvel);
    otherPanel.add(new JLabel("Acceleration"));
    otherPanel.add(this.ballacc);
    return otherPanel;
  }

  private void updatePane() {

    this.lpButton.setPlayer(this.clientScene.player[this.leftNumber]);
    this.lpos.setText(this
        .tuple2String(this.clientScene.player[this.leftNumber].pos));
    this.lvel.setText(this
        .tuple2String(this.clientScene.player[this.leftNumber].vel));
    this.lacc.setText(this
        .tuple2String(this.clientScene.player[this.leftNumber].acc));
    this.langle.setText(String
        .valueOf(this.clientScene.player[this.leftNumber].angle));
    this.lneck.setText(String
        .valueOf(this.clientScene.player[this.leftNumber].angleNeck));
    this.lvisible.setText(String
        .valueOf(this.clientScene.player[this.leftNumber].angleVisible));
    this.lmessage.setText(this.clientScene.player[this.leftNumber].sayMessage);
    this.lmessage.setCaretPosition(0);
    this.lcomment.setText(CommentDB.getComment(this.clientScene.time,
        this.leftNumber));
    this.rpButton.setPlayer(this.clientScene.player[this.rightNumber]);
    this.rpos.setText(this
        .tuple2String(this.clientScene.player[this.rightNumber].pos));
    this.rvel.setText(this
        .tuple2String(this.clientScene.player[this.rightNumber].vel));
    this.racc.setText(this
        .tuple2String(this.clientScene.player[this.rightNumber].acc));
    this.rangle.setText(String
        .valueOf(this.clientScene.player[this.rightNumber].angle));
    this.rneck.setText(String
        .valueOf(this.clientScene.player[this.rightNumber].angleNeck));
    this.rvisible.setText(String
        .valueOf(this.clientScene.player[this.rightNumber].angleVisible));
    this.rmessage.setText(this.clientScene.player[this.rightNumber].sayMessage);
    this.rmessage.setCaretPosition(0);
    this.rcomment.setText(CommentDB.getComment(this.clientScene.time,
        this.rightNumber));
    this.ballpos.setText(this.clientScene.ball.pos.toString());
    this.ballvel.setText(this.clientScene.ball.vel.toString());
    this.ballacc.setText(this.clientScene.ball.acc.toString());
  }

  public void setScene(ClientScene clientScene) {

    this.clientScene = clientScene;
    this.updatePane();
  }

  // �����Ѳ�����
  public void selectSoccerObject(int id,
      boolean flag) {

    if (id <= SoccerObjectID.LEFT_11) {
      this.leftNumber = id;
    }
    else if (id <= SoccerObjectID.RIGHT_11) {
      this.rightNumber = id;
    }
    this.updatePane();
  }

  // MouseListener
  public void mouseClicked(MouseEvent e) {

    Object o = e.getSource();
    // ������å�
    // ���ֹ�򥤥󥯥����
    if (e.getModifiers() == InputEvent.BUTTON1_MASK) {
      if (o == this.lpButton) {
        this.leftNumber = (this.leftNumber + 1) % Param.MAX_PLAYER;
      }
      else if (o == this.rpButton) {
        this.rightNumber = (this.rightNumber + 1) % Param.MAX_PLAYER + Param.MAX_PLAYER;
      }
    }
    // ������å�
    // ���ֹ��ǥ������
    else if (e.getModifiers() == InputEvent.META_MASK) {
      if (o == this.lpButton) {
        this.leftNumber = (this.leftNumber - 1 + Param.MAX_PLAYER) % Param.MAX_PLAYER;
      }
      else if (o == this.rpButton) {
        this.rightNumber = (this.rightNumber - 1) % Param.MAX_PLAYER + Param.MAX_PLAYER;
      }
    }
    this.updatePane();
  }

  public void mouseEntered(MouseEvent e) {

  }

  public void mouseExited(MouseEvent e) {

  }

  public void mousePressed(MouseEvent e) {

  }

  public void mouseReleased(MouseEvent e) {

  }
}
